﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Controls.Maps;
using Microsoft.Phone.Controls.Maps.Core;
using FBEventMaker.GeoCodeService;

//GPS
using System.Device.Location;
//Dispacher
using System.Windows.Threading;
using System.ServiceModel;
using Microsoft.Phone.Controls.Maps.Platform;

using System.Diagnostics;

namespace FBEventMaker
{
    public class GpsServiceEventArgs : EventArgs
    {
        public GeoCoordinate Location
        { get; set; }

        public string Address
        { get; set; }
    }

    public delegate void GpsServiceCompleted(object sender, GpsServiceEventArgs e);

    public class GpsServices
    {
        // this is the GPS 
        private const string m_AuthKey = "AlM6KcMAxUK_MLP_f94ltdDDVr3Kzyp-ese_UAq7qAP66Rwy27XFESuUABgOOQGp";
        private GeoCoordinateWatcher m_GeoWatcher = null;
        private GeoCoordinate m_Location;
        private string m_LocationAddress = "";
        private bool m_CurrentLocationAddressRequested = false;

        // Constructor
        public GpsServices()
        {
        }

        public event GpsServiceCompleted GpsServiceCompleted;

        public void GetCurrentLocation()
        {
            m_GeoWatcher = new GeoCoordinateWatcher();
            m_GeoWatcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(mGeoWatcher_PositionChanged);

            // starting the GPS
            m_GeoWatcher.Start();
        }

        public void GetLocationAddress(GeoCoordinate location)
        {
            m_Location = location;
            MakeReverseGeocodeRequest();
        }

        public void GetCurrentLocationAddress()
        {
            m_CurrentLocationAddressRequested = true;
            GetCurrentLocation();
        }

        private void mGeoWatcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
        {
            m_Location = e.Position.Location;

            // After getting one location, stop the watcher.
            Debug.Assert(m_GeoWatcher != null);
            m_GeoWatcher.Stop();

            if (!m_CurrentLocationAddressRequested)
            {
                OnGpsServiceCompleted();
            }
            else
            {
                MakeReverseGeocodeRequest();
            }
        }

        private void OnGpsServiceCompleted()
        {
            if (GpsServiceCompleted != null)
            {
                GpsServiceCompleted(this,
                    new GpsServiceEventArgs() { Location = m_Location, Address = m_LocationAddress });
            }
        }

        private void MakeReverseGeocodeRequest()
        {
            try
            {
                // Set a Bing Maps key before making a request
                GeoCodeService.ReverseGeocodeRequest reverseGeocodeRequest = new GeoCodeService.ReverseGeocodeRequest();

                // Set the credentials using a valid Bing Maps key
                reverseGeocodeRequest.Credentials = new Credentials();
                reverseGeocodeRequest.Credentials.ApplicationId = m_AuthKey;

                // Set the point to use to find a matching address
                GeoCodeService.GeocodeLocation point = new GeoCodeService.GeocodeLocation();
                point.Latitude = m_Location.Latitude;
                point.Longitude = m_Location.Longitude;

                reverseGeocodeRequest.Location = point;

                // Make the reverse geocode request
                GeoCodeService.GeocodeServiceClient geocodeService =
                new GeoCodeService.GeocodeServiceClient("BasicHttpBinding_IGeocodeService");
                geocodeService.ReverseGeocodeCompleted += (o, e) =>
                    {
                        if (e.Result != null && e.Result.Results != null && e.Result.Results.Count > 0)
                        {
                            m_LocationAddress = e.Result.Results[0].DisplayName;
                        }
                        else
                        {
                            m_LocationAddress = "";
                        }

                        OnGpsServiceCompleted();
                    };
                geocodeService.ReverseGeocodeAsync(reverseGeocodeRequest);

            }
            catch (Exception ex)
            {
                Console.WriteLine("Cannot find address : {0}", ex.Message);
            }
        }
    }
}